home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / comm2 / ipdilv19.lha / IPDial_v1.9 / Serial.c < prev    next >
C/C++ Source or Header  |  1995-11-17  |  17KB  |  749 lines

  1. /**
  2. ***  IPDial     Script program for initializing a SLIP connection
  3. ***  Copyright  (C)   1994    Jochen Wiedmann
  4. ***
  5. ***  This program is free software; you can redistribute it and/or modify
  6. ***  it under the terms of the GNU General Public License as published by
  7. ***  the Free Software Foundation; either version 2 of the License, or
  8. ***  (at your option) any later version.
  9. ***
  10. ***  This program is distributed in the hope that it will be useful,
  11. ***  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ***  GNU General Public License for more details.
  14. ***
  15. ***  You should have received a copy of the GNU General Public License
  16. ***  along with this program; if not, write to the Free Software
  17. ***  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ***
  19. ***
  20. ***
  21. ***  This file implements the communication with the serial.device.
  22. ***
  23. ***
  24. ***  Computer: Amiga 1200                       Compiler: Dice 3.01
  25. ***
  26. ***  Author:    Jochen Wiedmann
  27. ***             Am Eisteich 9
  28. ***             72555 Metzingen
  29. ***             Germany
  30. ***
  31. ***             Phone: (+0049) 7123 / 14881
  32. ***             Internet: wiedmann@neckar-alb.de
  33. **/
  34.  
  35. /**
  36. ***  Include files
  37. **/
  38. #ifndef IPDIAL_H
  39. #include "IPDial.h"
  40. #endif
  41. #include <ctype.h>
  42. #include <devices/serial.h>
  43. #include <devices/timer.h>
  44.  
  45. #ifndef MIN
  46. #define MIN(a,b) (((a)>(b))?(b):(a))
  47. #endif
  48.  
  49. /**
  50. ***  Local variables.
  51. **/
  52. STATIC APTR MySerReq            = NULL;
  53. STATIC APTR MyTimeReq           = NULL;
  54. STATIC UBYTE SerBuffer[4096];
  55.  
  56. /**
  57. ***  Cleanup function.
  58. **/
  59. VOID SerialCleanup(VOID)
  60.   DeviceIODelete(MySerReq);
  61.   DeviceIODelete(MyTimeReq);
  62. }
  63.  
  64. /**
  65. ***  Table of error messages created by the serial.device.
  66. **/
  67. STATIC VOID SerialShowError(ULONG Error)
  68.   STRPTR ptr;
  69.  
  70.   switch(Error)
  71.   { case 1:
  72.       ptr = (STRPTR) "Serial device busy";
  73.       break;
  74.     case 2:
  75.       ptr = (STRPTR) "Baud rate not supported";
  76.       break;
  77.     case 4:
  78.       ptr = (STRPTR) "Memory error";
  79.       break;
  80.     case 5:
  81.       ptr = (STRPTR) "Invalid parameters";
  82.       break;
  83.     case 6:
  84.       ptr = (STRPTR) "Line error";
  85.       break;
  86.     case 9:
  87.       ptr = (STRPTR) "Parity error";
  88.       break;
  89.     case 11:
  90.       ptr = (STRPTR) "Timer error";
  91.       break;
  92.     case 12:
  93.       ptr = (STRPTR) "Buffer overflow";
  94.       break;
  95.     case 13:
  96.       ptr = (STRPTR) "No DSR";
  97.       break;
  98.     case 15:
  99.       ptr = (STRPTR) "Break detected";
  100.       break;
  101.     default:
  102.       ptr = (STRPTR) "Unknown error";
  103.       break;
  104.   }
  105.  
  106.   fprintf(stderr, "Serial device: %s.\n", ptr);
  107. }
  108.  
  109. /**
  110. ***  This function opens the serial device. It can be closed
  111. ***  using DeviceIODelete().
  112. **/
  113. STATIC ULONG SerialDecodeProtocol(struct IOExtSer *SerReq, STRPTR Protocol)
  114.  
  115.   if (VerboseMode)
  116.     printf("\nSerialDecodeProtocol: Protocol %s\n", Protocol);
  117.  
  118.   if (stricmp((char *) Protocol, "XONXOFF") == 0)
  119.   { 
  120.     if (VerboseMode)
  121.       printf("SerialDecodeProtocol: Setting XON/XOFF\n");
  122.       
  123.     SerReq->io_SerFlags &= ~(SERF_XDISABLED|SERF_7WIRE);
  124.   }
  125.   else if (stricmp((char *) Protocol, "NONE") == 0)
  126.   { 
  127.     if (VerboseMode)
  128.       printf("SerialDecodeProtocol: Setting NONE\n");
  129.       
  130.     SerReq->io_SerFlags |= SERF_XDISABLED;
  131.     SerReq->io_SerFlags &= ~SERF_7WIRE;
  132.   }
  133.   else if (stricmp((char *) Protocol, "RTSCTS") == 0  ||
  134.              stricmp((char *) Protocol, "7WIRE") == 0)
  135.   { 
  136.     if (VerboseMode)
  137.       printf("SerialDecodeProtocol: Setting RTS/CTS and 7WIRE\n");
  138.       
  139.     SerReq->io_SerFlags |= (SERF_XDISABLED|SERF_7WIRE);
  140.   }
  141.   else
  142.   { 
  143.     if (VerboseMode)
  144.       printf("SerialDecodeProtocol: Unknown Protocol: %s\n", Protocol);
  145.       
  146.     return(FALSE);
  147.   }
  148.   return(TRUE);
  149. }
  150.  
  151. ULONG SerialOpen(STRPTR DeviceName, STRPTR Protocol, ULONG Unit)
  152.   ULONG error;
  153.   struct IOExtSer *RealSerReq;
  154.  
  155.   if (VerboseMode)
  156.     printf("\nSerialOpen: Device Name %s Protocol %s\n", DeviceName, Protocol);
  157.     
  158.   if (!(MySerReq = DeviceIOCreate(sizeof(struct IOExtSer))))
  159.   { 
  160.     fprintf(stderr, "Failed to open %s: Memory error.\n",
  161.         DeviceName);
  162.     exit(10);
  163.   }
  164.   RealSerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  165.   RealSerReq->io_SerFlags = 0;
  166.   if (Protocol)
  167.   { 
  168.     if (!SerialDecodeProtocol(RealSerReq, Protocol))
  169.     { 
  170.       return(FALSE);
  171.     }
  172.   }
  173.   if ((error = DeviceIOOpen(DeviceName, Unit, MySerReq, 0)))
  174.   { 
  175.     SerialShowError(error);
  176.     exit(10);
  177.   }
  178.   if (Protocol)
  179.   { 
  180.     SerialSetProtocol(Protocol);
  181.   }
  182.  
  183.   if (!(MyTimeReq = DeviceIOCreate(sizeof(struct timerequest))))
  184.   { 
  185.     fprintf(stderr, "Failed to open timer.device: Memory error.\n");
  186.     exit(10);
  187.   }
  188.   if ((error = DeviceIOOpen((STRPTR) "timer.device", UNIT_VBLANK,
  189.                                     MyTimeReq, 0)))
  190.   { 
  191.     fprintf(stderr, "Failed to open timer.device: Error %ld\n", error);
  192.     exit(10);
  193.   }
  194.   return(TRUE);
  195. }
  196.  
  197. /**
  198. ***  This function sends a string to the serial device.
  199. **/
  200. VOID SerialSend(STRPTR str, ULONG len)
  201.  
  202.   struct IOExtSer *req;
  203.  
  204.   if (VerboseMode)
  205.     printf("\nSerialSend: %s\n", str);
  206.  
  207.   req = (struct IOExtSer *) DeviceIOReq(MySerReq);
  208.   req->IOSer.io_Length = strlen((char*) str);
  209.   req->IOSer.io_Data = str;
  210.   DeviceIODo(MySerReq, CMD_WRITE);
  211. }
  212.  
  213. /**
  214. ***  This function is used to wait for a certain string.
  215. ***
  216. ***  The function will return if either a timeout occurs
  217. ***  (never happens, if timeout == -1) or if one of the
  218. ***  strings in the args array is read from the serial.device.
  219. ***
  220. ***  Result is the number of the string or -1.
  221. **/
  222. STATIC APTR waitBuffer = NULL;
  223. LONG SerialWait(STRPTR *args, LONG timeout)
  224.   ULONG sigs;
  225.   ULONG rsigs;
  226.   BYTE error;
  227.   struct IOExtSer *SerReq;
  228.   
  229.   if(VerboseMode)
  230.   {
  231.     int i=0;
  232.     printf("SerialWait: timeout = %d\n",timeout);
  233.     while(args[i])
  234.     {
  235.       printf("SerialWait: args[%d] %s \n",i,args[i]);
  236.       i++;
  237.     }
  238.   }
  239.   SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  240.  
  241.   /**
  242.   ***  Be sure, that the buffer is valid.
  243.   **/
  244.   if (!waitBuffer  &&  !(waitBuffer = BufferCreate()))
  245.   { 
  246.     perror("malloc");
  247.     exit(10);
  248.   }
  249.  
  250.   /**
  251.   ***  Clear the buffer.
  252.   **/
  253.   BufferClear(waitBuffer);
  254.  
  255.   sigs = SIGBREAKF_CTRL_C | DeviceIOSignal(MySerReq);
  256.  
  257.   if (timeout != -1)
  258.   { 
  259.     struct timerequest *tr = (struct timerequest *) DeviceIOReq(MyTimeReq);
  260.  
  261.     tr->tr_time.tv_secs = timeout;
  262.     tr->tr_time.tv_micro = 0;
  263.     DeviceIOSend(MyTimeReq, TR_ADDREQUEST);
  264.     sigs |= DeviceIOSignal(MyTimeReq);
  265.   }
  266.  
  267.   for(;;)
  268.   { 
  269.     LONG result;
  270.  
  271.     /**
  272.     ***  First ask, if any data is present on the serial line.
  273.     ***  May be, the string we are waiting for is already present?
  274.     **/
  275.     do
  276.     { 
  277.       DeviceIODo(MySerReq, SDCMD_QUERY);
  278.       if ((result = SerReq->IOSer.io_Actual))
  279.       { 
  280.         SerReq->IOSer.io_Data = SerBuffer;
  281.           SerReq->IOSer.io_Length = MIN(sizeof(SerBuffer)-1, 
  282.                                   SerReq->IOSer.io_Actual);
  283.         if ((error = DeviceIODo(MySerReq, CMD_READ)))
  284.           { 
  285.           SerialShowError(error);
  286.             exit(10);
  287.           }
  288.           if (EchoMode)
  289.           { 
  290.           int i;
  291.  
  292.             for (i = 0;  i < SerReq->IOSer.io_Actual;  i++)
  293.             { 
  294.             putchar(SerBuffer[i]);
  295.             }
  296.             fflush(stdout);
  297.           }
  298.           BufferExtend(waitBuffer, SerBuffer, SerReq->IOSer.io_Actual);
  299.       }
  300.     }
  301.     while (result);
  302.  
  303.  
  304.     if ((result = BufferCheck(waitBuffer, args)) >= 0)
  305.     { 
  306.       DeviceIOAbort(MyTimeReq);
  307.       if(VerboseMode)
  308.         printf("SerialWait: Exit line %d result = %d\n",__LINE__,result);
  309.        return(result);
  310.     }
  311.  
  312.     /**
  313.     ***  It isn't, send a request for one byte.
  314.     **/
  315.     SerReq->IOSer.io_Length = 1;
  316.     SerReq->IOSer.io_Data = SerBuffer;
  317.     DeviceIOSend(MySerReq, CMD_READ);
  318.  
  319.     rsigs = Wait(sigs);
  320.  
  321.     if (rsigs & SIGBREAKF_CTRL_C)
  322.     { 
  323.       printf("Ctrl-C\n");
  324.       exit(10);
  325.     }
  326.     else if (rsigs & DeviceIOSignal(MySerReq))
  327.     { 
  328.       BYTE error;
  329.  
  330.       /**
  331.       ***  Data received, add it to the buffer and check for more.
  332.       **/
  333.       if ((error = DeviceIOWait(MySerReq)))
  334.       { 
  335.         SerialShowError(error);
  336.           exit(10);
  337.       }
  338.       if (EchoMode)
  339.       { 
  340.         putchar(*SerBuffer);
  341.           fflush(stdout);
  342.       }
  343.       BufferExtend(waitBuffer, SerBuffer, 1);
  344.     }
  345.     else
  346.     { /**
  347.       ***  Timeout
  348.       **/
  349.       DeviceIOWait(MyTimeReq);
  350.       DeviceIOAbort(MySerReq);
  351.       if(VerboseMode)
  352.         printf("SerialWait: Timeout Exit line %d\n",__LINE__);
  353.       return(-1);
  354.     }
  355.   }
  356.   if(VerboseMode)
  357.     printf("SerialWait: Exit line %d\n",__LINE__);
  358. }
  359. /**
  360. ***  Return buffer read by the last "Wait" command.
  361. **/
  362. STRPTR SerialWaitBuffer(VOID)
  363. { if (!(waitBuffer))
  364.   { 
  365.     return((STRPTR) "");
  366.   }
  367.   else
  368.   { 
  369.     return(BufferBuffer(waitBuffer));
  370.   }
  371. }
  372. /**
  373. ***  This function implements a terminal mode. It gives the users input
  374. ***  to the modem and likewise the modems output to the user, as long as
  375. ***  the user doesn't enter Ctrl-\.
  376. **/
  377. VOID SerialTerminal(STRPTR eof, ULONG echo, ULONG lineMode)
  378.   struct DosPacket *dp;
  379.   struct MsgPort *port = NULL;
  380.   struct IOExtSer *SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  381.                             APTR SerSendReq = NULL;
  382.   struct IOExtSer *serSendReq;
  383.   char   buffer[128];
  384.   char   sendBuffer[256]; /* Twice the size of buffer */
  385.   ULONG  bufSize = sizeof(buffer);
  386.   ULONG  status = 10;
  387.   BPTR   cis = Input();
  388.   ULONG  sigs;
  389.  
  390.   if (!cis)
  391.   { 
  392.     fprintf(stderr, "Can't use nil: as input device.\n");
  393.     exit(10);
  394.   }
  395.  
  396.   if (!echo) 
  397.   {
  398.     lineMode = FALSE;
  399.   }
  400.   if (!lineMode) 
  401.   {
  402.     if (!SetMode(cis, TRUE)) 
  403.     {
  404.         fprintf(stderr, "Can't put console into character (raw) mode.\n");
  405.         exit(10);
  406.     }
  407.     bufSize = 128;
  408.   }
  409.  
  410.  
  411.   if ((dp = AllocDosObject(DOS_STDPKT, NULL)))
  412.   { if ((port = CreateMsgPort()))
  413.     { if ((SerSendReq = DeviceIOCreate(sizeof(struct IOExtSer))))
  414.       { 
  415.         serSendReq = (struct IOExtSer *) DeviceIOReq(SerSendReq);
  416.           serSendReq->IOSer.io_Device = SerReq->IOSer.io_Device;
  417.           serSendReq->IOSer.io_Unit = SerReq->IOSer.io_Unit;
  418.           status = 0;
  419.       }
  420.     }
  421.   }
  422.  
  423.   if (status)
  424.   { 
  425.     fprintf(stderr, "Memory error.\n");
  426.     goto ExitSerialTerminal;
  427.   }
  428.  
  429.   dp->dp_Type = ACTION_READ;
  430.   dp->dp_Arg1 = ((struct FileHandle *) BADDR(cis))->fh_Arg1;
  431.   dp->dp_Arg2 = (ULONG) buffer;
  432.   dp->dp_Arg3 = bufSize;
  433.   SendPkt(dp, (struct MsgPort *) ((struct FileHandle *) BADDR(cis))->fh_Type, 
  434.           port);
  435.  
  436.   SerReq->IOSer.io_Length = 1;
  437.   SerReq->IOSer.io_Data = SerBuffer;
  438.   DeviceIOSend(MySerReq, CMD_READ);
  439.  
  440.   sigs = (1 << port->mp_SigBit) | SIGBREAKF_CTRL_C | DeviceIOSignal(MySerReq);
  441.  
  442.   for(;;)
  443.   { 
  444.     LONG rsigs;
  445.     rsigs = Wait(sigs);
  446.     if (rsigs & SIGBREAKF_CTRL_C)
  447.     { 
  448.       fprintf(stderr, "Ctrl-C\n");
  449.       status = 5;
  450.       DeviceIOAbort(MySerReq);
  451.       AbortPkt(port, dp);
  452.       WaitPort(port);
  453.       goto ExitSerialTerminal;
  454.     }
  455.  
  456.     if (rsigs & (1 << port->mp_SigBit))
  457.     { int eofSeen = FALSE;
  458.       GetMsg(port);
  459.       if (dp->dp_Res1 == -1)
  460.       { 
  461.         fprintf(stderr, "Error %ld while reading input.\n", dp->dp_Res2);
  462.           status = 10;
  463.       }
  464.       if (dp->dp_Res1 == 0)
  465.       { 
  466.         eofSeen = TRUE;
  467.       }
  468.       else
  469.       { 
  470.         int i, bufLen;  /*  Extend LF to CR/LF and send resulting string.   */
  471.         bufLen = 0;
  472.           for (i = 0;  i < dp->dp_Res1;  i++)
  473.           { 
  474.           if ((eof  &&  *eof == buffer[i])  ||
  475.                 (!eof  &&  !lineMode  &&  buffer[i] == 0x1c))
  476.             { 
  477.              eofSeen = TRUE;
  478.             }
  479.             if (lineMode  &&  buffer[i] == '\n')
  480.             { 
  481.             sendBuffer[bufLen++] = '\r';
  482.               sendBuffer[bufLen++] = '\n';
  483.             }
  484.             else
  485.             { 
  486.             sendBuffer[bufLen++] = buffer[i];
  487.             }
  488.           }
  489.  
  490.           if (bufLen > 0)
  491.           { 
  492.           serSendReq->IOSer.io_Length = bufLen;
  493.             serSendReq->IOSer.io_Data = sendBuffer;
  494.             DeviceIODo(SerSendReq, CMD_WRITE);
  495.           }
  496.  
  497.           if (!lineMode  &&  echo)
  498.           { 
  499.           fwrite(sendBuffer, bufLen, 1, stdout);
  500.             fflush(stdout);
  501.           }
  502.       }
  503.  
  504.       if (eofSeen)
  505.       { 
  506.         DeviceIOAbort(MySerReq);
  507.         goto ExitSerialTerminal;
  508.       }
  509.       dp->dp_Type = ACTION_READ;
  510.       dp->dp_Arg1 = ((struct FileHandle *) BADDR(cis))->fh_Arg1;
  511.       dp->dp_Arg2 = (ULONG) buffer;
  512.       dp->dp_Arg3 = bufSize;
  513.       SendPkt(dp, (struct MsgPort *) ((struct FileHandle *) BADDR(cis))->fh_Type, port);
  514.     }
  515.  
  516.     if (rsigs & DeviceIOSignal(MySerReq))
  517.     { 
  518.       LONG error;
  519.       LONG result;
  520.  
  521.       if ((error = DeviceIOWait(MySerReq)))
  522.       { 
  523.         SerialShowError(error);
  524.         AbortPkt(port, dp);
  525.           WaitPort(port);
  526.           goto ExitSerialTerminal;
  527.       }
  528.       putchar(*SerBuffer);
  529.       fflush(stdout);
  530.  
  531.       do
  532.       { 
  533.         DeviceIODo(MySerReq, SDCMD_QUERY);
  534.           if ((result = SerReq->IOSer.io_Actual))
  535.           { 
  536.           SerReq->IOSer.io_Data = SerBuffer;
  537.             SerReq->IOSer.io_Length = MIN(sizeof(SerBuffer)-1, 
  538.                                     SerReq->IOSer.io_Actual);
  539.             if ((error = DeviceIODo(MySerReq, CMD_READ)))
  540.             { 
  541.             SerialShowError(error);
  542.               exit(10);
  543.             }
  544.             fwrite(SerBuffer, SerReq->IOSer.io_Actual, 1, stdout);
  545.             fflush(stdout);
  546.           }
  547.       }
  548.       while (result);
  549.  
  550.       SerReq->IOSer.io_Length = 1;
  551.       SerReq->IOSer.io_Data = SerBuffer;
  552.       DeviceIOSend(MySerReq, CMD_READ);
  553.     }
  554.   }
  555.  
  556.  
  557. ExitSerialTerminal:
  558.   if (dp)
  559.   { 
  560.     FreeDosObject(DOS_STDPKT, dp);
  561.   }
  562.   if (port)
  563.   { 
  564.     DeleteMsgPort(port);
  565.   }
  566.   if (SerSendReq)
  567.   { 
  568.     DeviceIODelete(SerSendReq);
  569.   }
  570.   if (!lineMode)
  571.   { 
  572.     SetMode(cis, FALSE);
  573.   }
  574.   if (status)
  575.   { 
  576.     exit(status);
  577.   }
  578. }
  579. /**
  580. ***  This function shows the current serial parameters.
  581. **/
  582. VOID SerialShowParms(VOID)
  583.   STRPTR Parity, Protocol;
  584.   struct IOExtSer *SerReq;
  585.   
  586.   if (VerboseMode)
  587.     printf("\nSerialShowParms\n");
  588.     
  589.   SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  590.  
  591.   printf("\tBaud = %ld\n", SerReq->io_Baud);
  592.   printf("\tDataBits = %ld\n", (ULONG) SerReq->io_ReadLen);
  593.   printf("\tStopBits = %ld\n", (ULONG) SerReq->io_StopBits);
  594.   printf("\tBufSize = %ld\n", SerReq->io_RBufLen);
  595.   if (SerReq->io_SerFlags & SERF_PARTY_ON)
  596.   { 
  597.     if (SerReq->io_SerFlags & SERF_PARTY_ODD)
  598.     { 
  599.       Parity = (STRPTR) "Odd";
  600.     }
  601.     else
  602.     { 
  603.       Parity = (STRPTR) "Even";
  604.     }
  605.   }
  606.   else
  607.   { 
  608.     Parity = (STRPTR) "None";
  609.   }
  610.   printf("\tParity = %s\n", Parity);
  611.   if (SerReq->io_SerFlags & SERF_7WIRE)
  612.   { 
  613.     if (SerReq->io_SerFlags & SERF_XDISABLED)
  614.     { 
  615.       Protocol = (STRPTR) "RTS/CTS";
  616.     }
  617.     else
  618.     { 
  619.       Protocol = (STRPTR) "RTS/CTS, XON/XOFF";
  620.     }
  621.   }
  622.   else
  623.   { 
  624.     if (SerReq->io_SerFlags & SERF_XDISABLED)
  625.     { 
  626.       Protocol = (STRPTR) "None";
  627.     }
  628.     else
  629.     { 
  630.       Protocol = (STRPTR) "XON/XOFF";
  631.     }
  632.   }
  633.   printf("\tProtocol = %s\n\n", Protocol);
  634. }
  635.  
  636. /**
  637. ***  Some functions for setting serial parameters.
  638. **/
  639. VOID SerialSetBaud(ULONG Baud)
  640.   struct IOExtSer *SerReq;
  641.   BYTE   error;
  642.   
  643.   if (VerboseMode)
  644.     printf("\nSerialSetBaud: %d\n", Baud);
  645.     
  646.   SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  647.  
  648.   SerReq->io_Baud = Baud;
  649.   if ((error = DeviceIODo(MySerReq, SDCMD_SETPARAMS)))
  650.   { 
  651.     SerialShowError(error);
  652.     exit(10);
  653.   }
  654. }
  655. VOID SerialSetDataBits(UBYTE DataBits)
  656.  
  657. { struct IOExtSer *SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  658.   BYTE error;
  659.  
  660.   SerReq->io_ReadLen = SerReq->io_WriteLen = DataBits;
  661.   if ((error = DeviceIODo(MySerReq, SDCMD_SETPARAMS)))
  662.   { SerialShowError(error);
  663.     exit(10);
  664.   }
  665. }
  666. VOID SerialSetStopBits(UBYTE StopBits)
  667.  
  668. { struct IOExtSer *SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  669.   BYTE error;
  670.  
  671.   SerReq->io_StopBits = StopBits;
  672.   if ((error = DeviceIODo(MySerReq, SDCMD_SETPARAMS)))
  673.   { SerialShowError(error);
  674.     exit(10);
  675.   }
  676. }
  677. VOID SerialSetBufSize(ULONG BufSize)
  678.  
  679. { struct IOExtSer *SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  680.   BYTE error;
  681.  
  682.   if (BufSize & 0x3f)
  683.   { fprintf(stderr,
  684.         "Warning: BufSize must be a multiple of 64, rounding up.\n");
  685.     BufSize = (BufSize & 0x3f) + 0x40;
  686.   }
  687.   SerReq->io_RBufLen = BufSize;
  688.   if ((error = DeviceIODo(MySerReq, SDCMD_SETPARAMS)))
  689.   { SerialShowError(error);
  690.     exit(10);
  691.   }
  692. }
  693. ULONG SerialSetParity(STRPTR Parity)
  694.  
  695. { struct IOExtSer *SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  696.   BYTE error;
  697.  
  698.   if (stricmp((char *) Parity, "NONE") == 0)
  699.   { SerReq->io_SerFlags &= ~SERF_PARTY_ON;
  700.   }
  701.   else if (stricmp((char *) Parity, "EVEN") == 0)
  702.   { SerReq->io_SerFlags |= SERF_PARTY_ON;
  703.     SerReq->io_SerFlags &= ~SERF_PARTY_ODD;
  704.   }
  705.   else if (stricmp((char *) Parity, "ODD") == 0)
  706.   { SerReq->io_SerFlags |= (SERF_PARTY_ON|SERF_PARTY_ODD);
  707.   }
  708.   else
  709.   { return(FALSE);
  710.   }
  711.  
  712.   if ((error = DeviceIODo(MySerReq, SDCMD_SETPARAMS)))
  713.   { SerialShowError(error);
  714.     exit(10);
  715.   }
  716.   return(TRUE);
  717. }
  718. ULONG SerialSetProtocol(STRPTR Protocol)
  719.   struct IOExtSer *SerReq;
  720.   BYTE error;
  721.   
  722.   if (VerboseMode)
  723.     printf("\nSerialSetProtocol: %s\n", Protocol);
  724.     
  725.   SerReq = (struct IOExtSer *) DeviceIOReq(MySerReq);
  726.  
  727.   if (!(SerialDecodeProtocol(SerReq, Protocol)))
  728.   { 
  729.     return(FALSE);
  730.   }
  731.  
  732.   if ((error = DeviceIODo(MySerReq, SDCMD_SETPARAMS)))
  733.   { 
  734.     SerialShowError(error);
  735.     exit(10);
  736.   }
  737.   return(TRUE);
  738. }
  739.